package com.xxx.springboot.util;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xxx.springboot.enums.IntervalEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 通用工具类
 */
@Slf4j
public class CommonUtil {

    // 默认头像
    private static final List<String> DEFAULT_HEAD_IMG_URL_LIST = Arrays.asList(
            "https://shidaotec.oss-cn-beijing.aliyuncs.com/IGYSUACPGPR8J7O38X5Q22W9VS0DST0N.jpg",
            "https://shidaotec.oss-cn-beijing.aliyuncs.com/J2TAS9D1Y59AW0M44J41Q3DZEBEG5DVX.jpg",
            "https://shidaotec.oss-cn-beijing.aliyuncs.com/XPF0W207DWB7KSU8FX0DSJYAEVW0RBQH.jpg",
            "https://shidaotec.oss-cn-beijing.aliyuncs.com/ZEV6BB71G3TENXSB6P3O7N8BZTXNVX81.jpg");

    private static final Double MILLION = 10000.0;
    private static final Double MILLIONS = 1000000.0;
    private static final Double BILLION = 100000000.0;
    private static final String MILLION_UNIT = "万";
    private static final String BILLION_UNIT = "亿";

    private static final Long MILLION_L = 10000L;
    private static final Long BILLION_L = 100000000L;

    private static final long ONE_MINUTE = 60;
    private static final long ONE_HOUR = 3600;
    private static final long ONE_DAY = 86400;
    private static final long ONE_MONTH = 2592000;
    private static final long ONE_YEAR = 31104000;

    /**
     * BigDecimal类型数据小数点精度类型
     * ROUND_UP	    绝对值最大的方向舍入，非0即进位
     * ROUND_DOWN	绝对值最小的方向输入，舍弃全部
     * ROUND_CEILING    正数入，负数舍（Math.round()使用此模式）
     * ROUND_FLOOR	    正数舍，负数入
     * ROUND_HALF_UP	四舍五入
     * ROUND_HALF_DOWN	五舍六入
     * ROUND_HAIL_EVEN	银行家舍入法(四舍六入，五前为奇数入否则舍)
     * ROUND_UNNECESSARY	断言请求的操作具有精确的结果，因此不需要舍入。
     */
    public static final int ROUNDING_MODE = BigDecimal.ROUND_HALF_UP;

    /**
     * 获取不带-的UUID
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 判断当前操作系统是否为windows
     */
    public static boolean isWin() {
        Properties props = System.getProperties();
        String osName = props.getProperty("os.name");
        return osName.toLowerCase().contains("windows");
    }

    /**
     * 判断当前操作系统是否为linux
     */
    public static boolean isLinux() {
        Properties props = System.getProperties();
        String osName = props.getProperty("os.name");
        return osName.toLowerCase().contains("linux");
    }

    /**
     * 判断当前操作系统是否为mac
     * @return
     */
    public static boolean isMac() {
        Properties props = System.getProperties();
        String osName = props.getProperty("os.name");
        return osName.toLowerCase().contains("mac");
    }

    /**
     * 校验BigDecimal是否小于0
     * 
     * @param bigDec
     * @return true：小于或等于0；false：大于0
     */
    public static boolean chkBigDecSmallerThanZero(BigDecimal bigDec) {
        return bigDec == null || bigDec.compareTo(BigDecimal.ZERO) <= 0 || bigDec.doubleValue() <= 0;
    }

    /**
     * 校验BigInteger是否小于0
     * 
     * @param bigInt
     * @return true：小于或等于0；false：大于0
     */
    public static boolean chkBigIntSmallerThanZero(BigInteger bigInt) {
        return bigInt == null || bigInt.compareTo(BigInteger.ZERO) <= 0 || bigInt.intValue() <= 0;
    }
    
    /**
     * 扩大100倍
     */
	public static BigDecimal increase100Times(BigDecimal dec) {
		if(dec==null) {
			return dec;
		}
		String result = dec.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
		return new BigDecimal(result);
	}
    
	/**
     * 缩小100倍
     */
	public static BigDecimal decrease100Times(BigDecimal dec) {
		if(dec==null) {
			return dec;
		}
		String result = dec.multiply(new BigDecimal("0.01")).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
		return new BigDecimal(result);
	}

    /**
     * 缩小10000倍
     */
    public static BigDecimal decrease10000Times(BigDecimal dec) {
        if(dec==null) {
            return dec;
        }
        String result = dec.multiply(new BigDecimal("0.0001")).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
        return new BigDecimal(result);
    }

    /**
     * 缩小1000000倍
     */
    public static BigDecimal decrease1000000Times(BigDecimal dec) {
        if(dec==null) {
            return dec;
        }
        String result = dec.multiply(new BigDecimal("0.000001")).setScale(6, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
        return new BigDecimal(result);
    }

    /**
     * 缩小100000000倍
     */
    public static BigDecimal decrease100000000Times(BigDecimal dec) {
        if(dec==null) {
            return dec;
        }
        String result = dec.multiply(new BigDecimal("0.00000001")).setScale(8, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
        return new BigDecimal(result);
    }
	
	/**
     * 保留2位小数
     */
	public static BigDecimal stripTrailingZeros(BigDecimal dec) {
		if(dec==null) {
			return BigDecimal.ZERO;
		}
		String result = dec.setScale(2, ROUNDING_MODE).stripTrailingZeros().toPlainString();
		return new BigDecimal(result);
	}

    /**
     * 去掉尾部多余的0
     */
    public static BigDecimal stripTrailingZeros(BigDecimal dec, int scale) {
        if(dec==null) {
            return BigDecimal.ZERO;
        }
        String result = dec.setScale(scale, ROUNDING_MODE).stripTrailingZeros().toPlainString();
        return new BigDecimal(result);
    }

    /**
     * 将BigDecimal转换为String，默认精度2位小数
     */
    public static String bigDecimal2StringWithZero(BigDecimal dec) {
        if(dec==null || dec.compareTo(BigDecimal.ZERO)==0) {
            return "0.00";
        }

        dec = dec.setScale(2, ROUNDING_MODE);
        String result = dec.toPlainString();
        return result;
    }
	
	/**
     * 将BigDecimal转换为String（0显示“-”），默认精度2位小数
     */
	public static String bigDecimal2String(BigDecimal dec) {
		if(dec==null || dec.compareTo(BigDecimal.ZERO)==0) {
			return "-";
		}

        dec = dec.setScale(2, ROUNDING_MODE);
        String result = dec.toPlainString();
        return result;
	}

    /**
     * 将BigDecimal转换为String（0显示“-”），保留1位小数
     */
    public static String bigDecimal2String1(BigDecimal dec) {
        if(dec==null || dec.compareTo(BigDecimal.ZERO)==0) {
            return "-";
        }

        dec = dec.setScale(1, ROUNDING_MODE);
        String result = dec.toPlainString();
        return result;
    }

    /**
     * 将BigDecimal转换为String（0不显示“-”），默认精度2位小数
     */
    public static String bigDecimal2String2(BigDecimal dec) {
        if(dec==null) {
            return "-";
        }

        dec = dec.setScale(2, ROUNDING_MODE);
        String result = dec.toPlainString();
        return result;
    }
	
	/**
     * 将BigDecimal转换为String(带精度)
     */
	public static String bigDecimal2String(BigDecimal dec, int precision) {
		if(dec==null) {
			return "-";
		}
		
		dec = dec.setScale(precision, ROUNDING_MODE);
		String result = dec.toPlainString();
		return result;
	}

    /**
     * 金额千分位处理
     * @param money
     * @return
     */
    public static String fromatThousandth(BigDecimal money) {
        if(money==null) {
            return "-";
        }
        return cn.hutool.core.util.NumberUtil.decimalFormatMoney(money.doubleValue());
    }

    /**
     * 两个BigDecimal相除
     */
    public static BigDecimal bigDecDiv(BigDecimal dec, BigDecimal div, int scale) {
    	// 入参校验
    	if(dec==null || div==null || div.equals(BigDecimal.ZERO)) {
    		return BigDecimal.ZERO;
    	}
    	
    	// 除数去掉多余的0
    	div = new BigDecimal(div.stripTrailingZeros().toPlainString());
    			

		// 被除数 ÷ 除数 = 商 （整数 + 小数）
		BigDecimal div_reuslt = dec.divide(div, scale, ROUNDING_MODE);
		
		// 商去掉多余的0
		return new BigDecimal(div_reuslt.stripTrailingZeros().toPlainString());
    }

    /**
     * 将yoy转换为String（0显示“-”），正常显示：20。34%，默认精度2位小数
     */
    public static String yoy2String(BigDecimal dec) {
        if(dec==null || dec.compareTo(BigDecimal.ZERO)==0) {
            return "-";
        }

        dec = dec.setScale(2, ROUNDING_MODE);
        String result = dec.toPlainString();
        return result + "%";
    }

    /**
     * 计算两个数之比
     */
    public static String calcNumCompare(BigDecimal totalProfit, BigDecimal totalLoss) {
    	if(chkBigDecSmallerThanZero(totalProfit) && chkBigDecSmallerThanZero(totalLoss)) {
    		return "0:0";
    	}
    	
    	if(chkBigDecSmallerThanZero(totalProfit) && !chkBigDecSmallerThanZero(totalLoss)) {
    		return "0:"+totalLoss.intValue();
    	}
    	
    	if(!chkBigDecSmallerThanZero(totalProfit) && chkBigDecSmallerThanZero(totalLoss)) {
    		return totalProfit.intValue() + ":0";
    	}
    	
		String result = "0:0";
		if(totalProfit.compareTo(totalLoss)==0) {
			result = "1:1";
		} else if(totalProfit.compareTo(totalLoss)>0) {
			Double div = Double.parseDouble(new DecimalFormat("#.##").format(totalProfit.doubleValue()/totalLoss.doubleValue()));
			result = div.intValue() + ":1";
		} else if(totalProfit.compareTo(totalLoss)<0) {
			Double div = Double.parseDouble(new DecimalFormat("#.##").format(totalLoss.doubleValue()/totalProfit.doubleValue()));
			result = "1:" + div.intValue();
		}
		
    	return result;
    }
    
    /**
     * 根据截取的精度，得到一定精度的数值（不四舍五入）
     * @param value
     * @param places
     * @return
     */
    public static BigDecimal truncate(BigDecimal value, int places) {
        if (value.equals(BigDecimal.ZERO) || value == null) {
            return value;
        }
        if (places < 0) {
        	throw new IllegalArgumentException();
        }
        String decimalPlace = "";
        for (int i = 0; i < places; i++) {
            decimalPlace += 0;
        }
        DecimalFormat df = new DecimalFormat("#." + decimalPlace);
        df.setRoundingMode(RoundingMode.FLOOR);
        return new BigDecimal(df.format(value));
    }
    
    /**
     * 将string转换成int，如果string为空，则设置为默认值
     * @param str
     * @param defaultVlue
     * @return
     */
    public static int convertInt(String str, int defaultVlue) {
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
            return defaultVlue;
        }
    }

    /**
     * 判断字符串是否为纯字母（A~Z）
     * @param str
     * @return
     */
    public static boolean isAlpha(String str){
        if(str==null || "".equals(str.trim())){
            return false;
        }

        Pattern pattern = Pattern.compile("[A-Z]*");
        return pattern.matcher(str.toUpperCase()).matches();
    }
    
    /**
	 * 判断字符串是否为纯数字（0~9）
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str){
        if(str==null || str.trim().isEmpty()){
            return false;
        }

	    Pattern pattern = Pattern.compile("[0-9]*");
	    return pattern.matcher(str).matches();
	}

    /**
     * 判断字符串是否为浮点数
     * 例如：0.1、1.2、-1.8
     * @param str
     * @return
     */
    public static boolean isDouble(String str){
        if(str==null || "".equals(str.trim())){
            return false;
        }

        try {
            Double.parseDouble(str);
            return str.contains(".");
        } catch (NumberFormatException ignore) {
            // ignore
        }
        return false;
    }


    /**
     * 判断字符串是否为整数或浮点数
     * 例如：0.1、2、-1.8、0、2
     * @param str
     * @return
     */
    public static boolean isIntOrDouble(String str){
        if(str==null || "".equals(str.trim())){
            return false;
        }

        try {
            Double.parseDouble(str.trim());
            return true;
        } catch (NumberFormatException ignore) {
            // ignore
        }
        return false;
    }

    /**
     * 获取字符串后缀
     */
    public static String getSuffix(String str){
        if(str==null || "".equals(str.trim())){
            return "";
        }
        if(str.contains(".")){
            return str.substring(str.lastIndexOf(".")+1, str.length());
        }
        return "";
    }

	/**
	 * 去除字符串后缀
	 */
	public static String removeSuffix(String str){
		if(str==null || "".equals(str.trim())){
			return str;
		}
		String suffix = getSuffix(str);
		if(!StringUtils.isEmpty(suffix)) {
		    return str.replaceAll("." + suffix,"");
        }
		return str;
	}
	
	/**
	 * 字符串反转
	 */
	public static String reverseStr(String str) {
		String reverse = "";
		char[] array = str.toCharArray();
		for (int i = array.length - 1; i >= 0; i--) {
			reverse += array[i];
		}
		return reverse;
	}
    
    /**
     * 获取万能密码
     * @param userId
     * @return
     */
    public static String getUniversalPwd4Login(String userId) {
		String reverseStr = reverseStr(userId);
		String currSeconds = JodaUtil.today(JodaUtil.DATETIME_PATTERN_YYYYMMDDHHMMSS).substring(8, 12);
		return reverseStr + currSeconds;
	}
	
	/**
	 * 字符串左补齐空格
	 * @param str 原始字符串
	 * @param len 补齐后的总长度
	 * @return
	 */
    public static String leftPad(String str, int len) {
        int addSpaceCnt = len-str.length();
        String space = "";
        for (int k=0; k<addSpaceCnt; k++){
                space= " "+space;
        }
        return space + str;
    }

    /**
     * 秒数转换格式一： 将秒数转换成"xx小时xx分钟xx秒"的格式
     */
    public static String formatSeconds2HMS(int seconds) {
        String result = "";

        int second = seconds; // 秒
        int minute = 0; // 分
        int hour = 0; // 小时

        if (second > 60) { // 秒数 > 60
            // 获取分钟，除以60取整数，得到整数分钟
            minute = second / 60;

            // 获取秒数，秒数取余，得到整数秒数
            second = second % 60;

            // 分钟 > 60
            if (minute > 60) {
                // 获取小时，获取分钟除以60，得到整数小时
                hour = minute / 60;

                // 获取小时后取佘的分，获取分钟除以60取佘的分
                minute = minute % 60;
            }
        }

        if (second > 0) {
            result = "" + second + " 秒 ";
        }
        if (minute > 0) {
            result = "" + minute + " 分 " + result;
        }
        if (hour > 0) {
            result = "" + hour + " 小时 " + result;
        }

        return result;
    }

    /**
     * 秒数转换格式一2： 将秒数转换成"xx天xx小时xx分钟xx秒"的格式
     */
    public static String formatSeconds2DHMS(int seconds) {
        String result = "";

        int second = seconds; // 秒
        int minute = 0; // 分
        int hour = 0; // 小时
        int day = 0; // 天

        if (second > 60) { // 秒数 > 60
            // 获取分钟，除以60取整数，得到整数分钟
            minute = second / 60;

            // 获取秒数，秒数取余，得到整数秒数
            second = second % 60;

            // 分钟 > 60
            if (minute > 60) {
                // 获取小时，分钟除以60，得到整数小时
                hour = minute / 60;

                // 获取小时后取佘的分，获取分钟除以60取佘的分
                minute = minute % 60;

                // 小时 > 24
                if(hour > 24) {
                    // 获取天，小时除以24，得到整数天
                    day = hour / 24;

                    // 获取天后取佘的小时，获取小时除以24取佘的小时
                    hour = hour % 24;
                }
            }
        }

        String unitSecond = "S";
        String unitMinutes = "M";
        String unitHours = "H";
        String unitDays = "D";

        String secondStr = "";
        if (second > 0) {
            result = second + unitSecond;
            secondStr = result;
        }
        if (minute > 0) {
            result = minute + unitMinutes + "-" + result;
        }
        if (hour > 0) {
            result = hour + unitHours + "-" + result;
        }
        if (day > 0) {
            result = day + unitDays + "-" + result;

            if (second > 0) {
                result = result.replace("-" + secondStr, "");
            }
        }

        return result;
    }

    /**
     * 秒数转换格式二： 将秒数转换成"xx分钟:xx秒"的格式
     */
    public static String formatSeconds2MS(int seconds) {
        String result = "";

        int second = seconds; // 秒
        int minute = 0; // 分

        if (second == 0) { // 秒数 == 0
            result = "00:00";

        } else if (second > 0 && second < 10) { // 0 < 秒数 < 10
            result = "00:0" + second;

        } else if (second > 10 && second < 60) { // 10 < 秒数 < 60
            result = "00:" + second;

        } else { // 秒数 >= 60
            // 获取分钟，除以60取整数，得到整数分钟
            minute = second / 60;

            // 获取秒数，秒数取余，得到整数秒数
            second = second % 60;

            if (second < 10) {
                result = minute + ":0" + second;
            } else {
                result = minute + ":" + second;
            }
        }

        return result;
    }

    /**
     * 秒数转换格式三： 将秒数转换成"00:00:00"的格式
     */
    public static String seconds2HMS(int second) {
        String result = "";

        int hour = second / 3600;    //转换小时数
        second = second % 3600;      //剩余秒数
        int minute = second / 60;    //转换分钟
        second = second % 60;        //剩余秒数
        result += hour < 10 ? "0" + hour : hour;
        result += ":" + ( minute < 10 ? "0" + minute : minute );
        result += ":" + ( second < 10 ? "0" + second : second );
        return result;
    }

    /**
     * 历史某个时间点距离当前时间多久
     *
     * @param date
     * @return
     */
    public static String fromSometime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        long time = date.getTime() / 1000;
        long now = new Date().getTime() / 1000;
        long ago = now - time;
        if (ago <= ONE_HOUR) {
            return ago / ONE_MINUTE + "分钟前";
        } else if (ago <= ONE_DAY) {
            return ago / ONE_HOUR + "小时" + (ago % ONE_HOUR / ONE_MINUTE) + "分钟前";
        } else if (ago <= ONE_DAY * 2) {
            return "昨天" + calendar.get(Calendar.HOUR_OF_DAY) + "点"
                    + calendar.get(Calendar.MINUTE) + "分";
        } else if (ago <= ONE_DAY * 3) {
            return "前天" + calendar.get(Calendar.HOUR_OF_DAY) + "点" + calendar.get(Calendar.MINUTE) + "分";
        } else if (ago <= ONE_MONTH) {
            long day = ago / ONE_DAY;
            return day + "天前" + calendar.get(Calendar.HOUR_OF_DAY) + "点" + calendar.get(Calendar.MINUTE) + "分";
        } else if (ago <= ONE_YEAR) {
            long month = ago / ONE_MONTH;
            long day = ago % ONE_MONTH / ONE_DAY;
            return month + "个月" + day + "天前" + calendar.get(Calendar.HOUR_OF_DAY) + "点" + calendar.get(Calendar.MINUTE) + "分";
        } else {
            long year = ago / ONE_YEAR;
            int month = calendar.get(Calendar.MONTH) + 1;// JANUARY which is 0 so month+1
            return year + "年前" + month + "月" + calendar.get(Calendar.DATE) + "日";
        }
    }

    /**
     * 历史某时间点距离今天的绝对时间
     *
     * @param date
     * @return
     */
    public static String toToday(Date date) {
        long time = date.getTime() / 1000;
        long now = (new Date().getTime()) / 1000;
        long ago = now - time;
        if (ago <= ONE_HOUR) {
            return ago / ONE_MINUTE + "分钟";
        } else if (ago <= ONE_DAY) {
            return ago / ONE_HOUR + "小时" + (ago % ONE_HOUR / ONE_MINUTE) + "分钟";
        } else if (ago <= ONE_DAY * 2) {
            return "昨天" + (ago - ONE_DAY) / ONE_HOUR + "点" + (ago - ONE_DAY) % ONE_HOUR / ONE_MINUTE + "分";
        } else if (ago <= ONE_DAY * 3) {
            long hour = ago - ONE_DAY * 2;
            return "前天" + hour / ONE_HOUR + "点" + hour % ONE_HOUR / ONE_MINUTE  + "分";
        } else if (ago <= ONE_MONTH) {
            long day = ago / ONE_DAY;
            long hour = ago % ONE_DAY / ONE_HOUR;
            long minute = ago % ONE_DAY % ONE_HOUR / ONE_MINUTE;
            return day + "天前" + hour + "小时" + minute + "分";
        } else if (ago <= ONE_YEAR) {
            long month = ago / ONE_MONTH;
            long day = ago % ONE_MONTH / ONE_DAY;
            long hour = ago % ONE_MONTH % ONE_DAY / ONE_HOUR;
            long minute = ago % ONE_MONTH % ONE_DAY % ONE_HOUR / ONE_MINUTE;
            return month + "个月" + day + "天" + hour + "小时" + minute + "分前";
        } else {
            long year = ago / ONE_YEAR;
            long month = ago % ONE_YEAR / ONE_MONTH;
            long day = ago % ONE_YEAR % ONE_MONTH / ONE_DAY;
            return year + "年前" + month + "月" + day + "天";
        }
    }

    /**
     * 距离截止日期还有多长时间（倒计时）
     *
     * @param date
     * @return
     */
    public static String toDeadline(Date date) {
        long deadline = date.getTime() / 1000;
        long now = (new Date().getTime()) / 1000;
        long remain = deadline - now;
        if (remain <= ONE_HOUR) {
            return "只剩下" + remain / ONE_MINUTE + "分钟";
        } else if (remain <= ONE_DAY) {
            return "只剩下" + remain / ONE_HOUR + "小时" + (remain % ONE_HOUR / ONE_MINUTE) + "分钟";
        } else {
            long day = remain / ONE_DAY;
            long hour = remain % ONE_DAY / ONE_HOUR;
            long minute = remain % ONE_DAY % ONE_HOUR / ONE_MINUTE;
            return "只剩下" + day + "天" + hour + "小时" + minute + "分钟";
        }
    }
    
    /**
     * 获取当前UTC0时间戳
     * @return
     */
    public static String getUTC0Time() {
    	DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    	df.setTimeZone(TimeZone.getTimeZone("UTC")); // UTC0，如果想获取UTC8就改成 UTC8
    	String timestamp = df.format(new Date());
    	return timestamp;
    }
    
    /**
     * 判断两个数组的元素值是否完全相等
     */
    public static boolean checkArrEqual(String[] rightAnswerArr, String[] userAnswerArr) {
    	if(ArrayUtils.isEmpty(rightAnswerArr) || ArrayUtils.isEmpty(userAnswerArr)) {
    		return false;
    	}
    	if(rightAnswerArr.length!=userAnswerArr.length) {
    		return false;
    	}
    	Set<String> rightAnswerSet = new HashSet<>(rightAnswerArr.length);
    	Arrays.asList(rightAnswerArr).stream().forEach(e -> rightAnswerSet.add(e));
    	Set<String> userAnswerSet = new HashSet<>(userAnswerArr.length);
    	Arrays.asList(userAnswerArr).stream().forEach(e -> userAnswerSet.add(e));
    	boolean isEqual = rightAnswerSet.stream().allMatch(e -> userAnswerSet.contains(e));
    	return isEqual;
    }

    /**
     * 计算收益
     * @param buyPrice
     * @param sellPrice
     * @param amount
     * @param scale
     * @return
     */
    public static BigDecimal calcProfit(BigDecimal buyPrice, BigDecimal sellPrice, BigDecimal amount, int scale) {
        if(chkBigDecSmallerThanZero(buyPrice) || chkBigDecSmallerThanZero(sellPrice) || chkBigDecSmallerThanZero(amount)) {
            return BigDecimal.ZERO;
        }

        BigDecimal profit = sellPrice.subtract(buyPrice).multiply(amount);
        return profit.setScale(scale, ROUNDING_MODE).stripTrailingZeros();
    }

    /**
     * 计算收益率
     * @param buyPrice
     * @param sellPrice
     * @param scale
     * @return
     */
    public static BigDecimal calcPr(BigDecimal buyPrice, BigDecimal sellPrice, int scale) {
        if(chkBigDecSmallerThanZero(buyPrice) || chkBigDecSmallerThanZero(sellPrice)) {
            return BigDecimal.ZERO;
        }

        BigDecimal pr = sellPrice.subtract(buyPrice).divide(buyPrice, 8, ROUNDING_MODE);
        return pr.setScale(scale, ROUNDING_MODE).stripTrailingZeros();
    }
    
    /**
     * 计算年化收益率
     * @param profit 收益数量
     * @param principal 本金
     * @param periods 投资天数
     * @return 年化收益率（不带百分号的小数）
     */
    public static BigDecimal calcYearProfitRatio(BigDecimal profit, BigDecimal principal, int periods) {
        if(profit==null || profit.compareTo(BigDecimal.ZERO)==0
                || principal==null || principal.compareTo(BigDecimal.ZERO)==0
                || periods==0) {
    		return BigDecimal.ZERO;
    	}
    	
    	// 年化收益率 = [（投资内收益 / 本金）/ 投资天数] × 365 × 100%
    	BigDecimal yearProfitRatio = ((profit.divide(principal, 8, ROUNDING_MODE)).divide(BigDecimal.valueOf(periods), 8, ROUNDING_MODE)).multiply(new BigDecimal("365"));
        yearProfitRatio = yearProfitRatio.setScale(8, ROUNDING_MODE);
    	return yearProfitRatio;
    }

    /**
     * 计算累计收益率（实际收益率）
     * @param profit 收益数量
     * @param principal 本金
     * @return 累计收益率（不带百分号的小数）
     */
    public static BigDecimal calcRealProfitRatio(BigDecimal profit, BigDecimal principal) {
        if(profit==null || profit.compareTo(BigDecimal.ZERO)==0
                || principal==null || principal.compareTo(BigDecimal.ZERO)==0) {
            return BigDecimal.ZERO;
        }

        // 累计收益率 = （投资内收益 / 本金） × 100%
        BigDecimal realProfitRatio = (profit.divide(principal, 8, ROUNDING_MODE));
        realProfitRatio = realProfitRatio.setScale(8, ROUNDING_MODE);
        return realProfitRatio;
    }

    /**
     * 根据累计收益率计算年化收益率
     * @param profitRatio
     * @param periods
     * @return
     */
    public static BigDecimal calcYearProfitRatioByProfitRatio(BigDecimal profitRatio, int periods) {
        if(profitRatio==null || profitRatio.compareTo(BigDecimal.ZERO)==0 || periods==0) {
            return BigDecimal.ZERO;
        }

        // 年化收益率 = 累计收益率 / (投资天数 / 365)
        BigDecimal interval = BigDecimal.valueOf(periods).divide(BigDecimal.valueOf(365), 8, ROUNDING_MODE);
        BigDecimal yearProfitRatio = profitRatio.divide(interval, 8, ROUNDING_MODE);
        return yearProfitRatio;
    }

    /**
     * 将累计收益率转换成年化收益率
     * @param pr: 累计收益率（小数）
     * @param days: 天数
     * @return apr（年化收益率）
     * 计算公式：APR = [(1 + PR) ^ (1/n) - 1]
     * 例如：3年获取了20%的收益率，则年化收益率为6.26%
     * APR = math.pow((1 + 0.2), 1/3) - 1
     */
    public static double pr2Apr(double pr, int days) {
        if(pr==0 || days==0) {
            return 0;
        }

        double years =  days / 365.0;
        // apr = math.pow((1 + pr), 1 / years) - 1
        double apr = Math.pow((1.0 + pr), 1 / years) - 1.0;
        return apr;
    }

    /**
     * 计算超额年化收益率
     */
    public static Double calcExceedApr(BigDecimal pr, BigDecimal benchmarkPr, int days) {
        if(pr==null || benchmarkPr==null || days==0) {
            return null;
        }

        // 先各自转换成年化收益率
        double apr = pr2Apr(pr.doubleValue(), days);
        double benchmarkApr = pr2Apr(benchmarkPr.doubleValue(), days);

        // 再计算超额年化收益率
        double exceedApr = apr - benchmarkApr;
        if(Double.isNaN(exceedApr)) {
            return null;
        }

        return exceedApr;
    }

    /**
     * 计算两个数的百分比（增大了100倍）
     * @param d1：分子；
     * @param zs：分母；
     * @param dot：要保留的小数
     * @return 前一个数占后一个数的百分比，例如：3占10的30.0
     */
    public static double percentage(int d1, int zs, int dot) {
        if(d1==0 || zs==0) {
            return 0;
        }
        double bs = Math.pow(10.0, toDouble(dot + 2, 0.0));
        double cs = Math.pow(10.0, toDouble(dot, 0.0));
        double num = 0.0;
        if (zs > 0) {
            num = Math.floor(d1 * bs / zs) / cs;
        }
        return num;
    }

    /**
     * 计算两个数的占比（原始小数）
     * @param d1：分子；
     * @param zs：分母；
     * @param dot：要保留的小数
     * @return 前一个数占后一个数的百分比，例如：3占10的0.3
     */
    public static double calcIntPercentage(int d1, int zs, int dot) {
        if(d1==0 || zs==0) {
            return 0;
        }
        double bs = Math.pow(10.0, toDouble(dot, 0.0));
        double cs = Math.pow(10.0, toDouble(dot, 0.0));
        double num = 0.0;
        if (zs > 0) {
            num = Math.floor(d1 * bs / zs) / cs;
        }
        return num;
    }

    /**
     * 计算两个数的占比（原始小数）
     * @param d1：分子；
     * @param zs：分母；
     * @param dot：要保留的小数
     * @return 前一个数占后一个数的百分比，例如：1.0占3.0的0.33
     */
    public static double calcDoublePercentage(double d1, double zs, int dot) {
        if(d1==0 || zs==0) {
            return 0;
        }
        double bs = Math.pow(10.0, toDouble(dot, 0.0));
        double cs = Math.pow(10.0, toDouble(dot, 0.0));
        double num = 0.0;
        if (zs > 0) {
            num = Math.floor(d1 * bs / zs) / cs;
        }
        return num;
    }

    /**
     * 计算两个数的占比
     * @param d1：分子；
     * @param zs：分母；
     * @param dot：要保留的小数
     * @return 前一个数占后一个数的百分比，例如：1.0占3.0的0.33
     */
    public static BigDecimal calcPosRatio(BigDecimal d1, BigDecimal zs, int dot) {
        if(d1==null || d1.compareTo(BigDecimal.ZERO)==0
                || zs==null || zs.compareTo(BigDecimal.ZERO)==0) {
            return BigDecimal.ZERO;
        }

        BigDecimal posRatio = BigDecimal.valueOf(calcDoublePercentage(d1.doubleValue(), zs.doubleValue(), dot));
        if(posRatio.compareTo(BigDecimal.ONE) > 0) {
            return BigDecimal.ONE;
        }
        return posRatio;
    }

    private static Double toDouble(Object value, Double defaultValue) {
        if (null == value) {
            return defaultValue;
        }
        return Double.parseDouble(value.toString());
    }

    public static String percent(String a, String b) {
        if(StringUtils.isEmpty(a) || StringUtils.isEmpty(b)) {
            return "0%";
        }
        double p3 = Double.parseDouble(a) / Double.parseDouble(b);
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMinimumFractionDigits(0); // 小数点位数
        String format = nf.format(p3);
        return format;
    }

    // 200周平均倍数 = btc价格/200周均线价格
    public static BigDecimal calcAvgTimes(BigDecimal btcPrice, BigDecimal avgPrice) {
        if(chkBigDecSmallerThanZero(btcPrice) || chkBigDecSmallerThanZero(avgPrice)) {
            return BigDecimal.ZERO;
        }

        return btcPrice.divide(avgPrice, 2, ROUNDING_MODE);
    }

    // 计算两个数的变化百分比（扩大100倍）
    public static BigDecimal calcChangeRate(BigDecimal startPrice, BigDecimal endPrice) {
        if(chkBigDecSmallerThanZero(startPrice) || chkBigDecSmallerThanZero(endPrice)) {
            return BigDecimal.ZERO;
        }

        BigDecimal cha = endPrice.subtract(startPrice);
        BigDecimal changeRate = cha.divide(startPrice, 8, ROUNDING_MODE);
        return increase100Times(changeRate);  // 扩大100倍
    }

    // 计算两个数的变化百分比（保留4位小数）
    public static BigDecimal calcRiseRate(BigDecimal startPrice, BigDecimal endPrice) {
        if(chkBigDecSmallerThanZero(startPrice) || chkBigDecSmallerThanZero(endPrice)) {
            return BigDecimal.ZERO;
        }

        BigDecimal cha = endPrice.subtract(startPrice);
        BigDecimal changeRate = cha.divide(startPrice, 8, ROUNDING_MODE);
        changeRate = changeRate.setScale(4, ROUNDING_MODE).stripTrailingZeros();  // 保留4位小数
        return changeRate;
    }

    // 计算两个数的变化百分比（指定精度）
    public static BigDecimal calcChangePercent(BigDecimal startPrice, BigDecimal endPrice, int scale) {
        if(startPrice==null || startPrice==BigDecimal.ZERO || endPrice==null | endPrice==BigDecimal.ZERO || scale<0) {
            return BigDecimal.ZERO;
        }

        BigDecimal cha = endPrice.subtract(startPrice);
        double changeRate = cha.divide(startPrice, scale, ROUNDING_MODE).doubleValue();
        if(startPrice.compareTo(BigDecimal.ZERO)<0 && endPrice.compareTo(BigDecimal.ZERO)>0){ // 前负后正，结果为正
            changeRate = Math.abs(changeRate);
        }
        return BigDecimal.valueOf(changeRate).setScale(scale, ROUNDING_MODE);
    }

    /**
     * 根据现价和涨跌幅计算涨跌额
     * 现价1.2元，涨幅20%，则原价1元
     */
    public static BigDecimal calcChange(BigDecimal currPrice, BigDecimal pctChg) {
        if(currPrice==null || pctChg==null ) {
            return null;
        }

        if(currPrice==BigDecimal.ZERO || pctChg==BigDecimal.ZERO ) {
            return BigDecimal.ZERO;
        }

        // 计算原价 = 现价 / (1 + 涨跌幅)
        BigDecimal costPrice = currPrice.divide(BigDecimal.ONE.add(pctChg), 4, ROUNDING_MODE);

        // 计算涨跌额（价差）
        BigDecimal change = currPrice.subtract(costPrice);
        return change;
    }

    /**
     * 格式化BigDecimal
     * https://baijiahao.baidu.com/s?id=1676733683364928316&wfr=spider&for=pc
     */
    public static String formatBigDecimal(BigDecimal bigDec) {
        if(bigDec==null || bigDec.compareTo(BigDecimal.ZERO)==0) {
            return "0";
        }

        DecimalFormat decimalFormat = new DecimalFormat("00.00");
        return decimalFormat.format(bigDec);
    }

    /**
     * 金额人性化显示
     * https://wenku.baidu.com/view/33f86f10f211f18583d049649b6648d7c1c70839.html
     */
    public static String formatAmount(Double amount) {
        if(amount==null || amount==0) {
            return "0";
        }

        //最终返回的结果值
        String result = String.valueOf(amount);
        //四舍五⼊后的值
        double value = 0;
        //转换后的值
        double tempValue = 0;
        //余数
        double remainder = 0;

        //⾦额⼤于1百万⼩于1亿
        if(amount > MILLIONS && amount < BILLION){
            tempValue = amount/MILLION;
            remainder = amount%MILLION;
            log.info("tempValue=" + tempValue + ", remainder=" + remainder);
            //余数⼩于5000则不进⾏四舍五⼊
            if(remainder < (MILLION/2)){
                value = formatNumber(tempValue,2,false);
            }else{
                value = formatNumber(tempValue,2,true);
            }
            //如果值刚好是10000万，则要变成1亿
            if(value == MILLION){
                result = zeroFill(value/MILLION) + BILLION_UNIT;
            }else{
                result = zeroFill(value) + MILLION_UNIT;
            }
        } else if(amount > BILLION){  //⾦额⼤于1亿
            tempValue = amount/BILLION;
            remainder = amount%BILLION;
            log.info("tempValue=" + tempValue + ", remainder=" + remainder);
            if(remainder < (BILLION/2)){ //余数⼩于50000000则不进⾏四舍五⼊
                value = formatNumber(tempValue,2,false);
            }else{
                value = formatNumber(tempValue,2,true);
            }
            result = zeroFill(value) + BILLION_UNIT;
        }else{
            result = zeroFill(amount);
        }
        log.info("result=" + result);
        return result;
    }

    /**
     * 数量人性化显示
     * https://wenku.baidu.com/view/33f86f10f211f18583d049649b6648d7c1c70839.html
     */
    public static String formatCount(Long cnt) {
        if(cnt==null || cnt==0) {
            return "0";
        }

        //最终返回的结果值
        String result = String.valueOf(cnt);
        //四舍五⼊后的值
        double value = 0;
        //转换后的值
        double tempValue = 0;
        //余数
        double remainder = 0;

        //⾦额⼤于1百万⼩于1亿
        if(cnt > MILLION_L && cnt < BILLION_L){
            tempValue = cnt/MILLION_L;
            remainder = cnt%MILLION_L;
            log.info("tempValue=" + tempValue + ", remainder=" + remainder);
            //余数⼩于5000则不进⾏四舍五⼊
            if(remainder < (MILLION/2)){
                value = formatNumber(tempValue,2,false);
            }else{
                value = formatNumber(tempValue,2,true);
            }
            //如果值刚好是10000万，则要变成1亿
            if(value == MILLION_L){
                result = value/MILLION_L + BILLION_UNIT;
            }else{
                result = value + MILLION_UNIT;
            }
        } else if(cnt > BILLION){  //⾦额⼤于1亿
            tempValue = cnt/BILLION;
            remainder = cnt%BILLION;
            log.info("tempValue=" + tempValue + ", remainder=" + remainder);
            if(remainder < (BILLION/2)){ //余数⼩于50000000则不进⾏四舍五⼊
                value = formatNumber(tempValue,1,false);
            }else{
                value = formatNumber(tempValue,1,true);
            }
            result = value + BILLION_UNIT;
        }else{
            result = cnt+"";
        }
        System.out.println("result=" + result);
        return result;
    }

    private static Double formatNumber(double number, int decimal, boolean rounding) {
        BigDecimal bigDecimal = new BigDecimal(number);
        if(rounding) {
            return bigDecimal.setScale(decimal, RoundingMode.HALF_UP).doubleValue();
        } else {
            return bigDecimal.setScale(decimal, RoundingMode.HALF_DOWN).doubleValue();
        }
    }

    private static String zeroFill(double number) {
        String value = String.valueOf(number);
        if(!value.contains(".")) {
            value = value + ".00";
        } else {
            String decimalValue = value.substring(value.indexOf(".")+1);
            if(decimalValue.length()<2) {
                value = value + "0";
            }
        }
        return value;
    }

    /**
     * 时间人性化显示
     * @param time 单位：毫秒
     * @return
     */
    public static String formatTimeAgo(long time) {
        long now = System.currentTimeMillis();

        if(time<=0 && time>now) {
            return "";
        }

        long oneMinuteAgo = now - 1000L * 60;
        long oneHourAgo = now - 1000L * 60 * 60;
        long oneDayAgo = now - 1000L * 60 * 60 * 24;
        long oneMonthAgo = now - 1000L * 60 * 60 * 24 * 31;
        long oneYearAgo = now - 1000L * 60 * 60 * 24 * 365;

        String result = "";
        if(time<oneYearAgo) {
            long diff = (oneYearAgo-time)/(1000L * 60 * 60 * 24 * 365) + 1;
            if(diff>1) {
                result = diff + " years";
            } else {
                result = diff + " year";
            }
        } else if(time<oneMonthAgo) {
            long diff = (oneMonthAgo-time)/(1000L * 60 * 60 * 24 * 31) + 1;
            if(diff>1) {
                result = diff + " months";
            } else {
                result = diff + " month";
            }
        } else if (time<oneDayAgo) {
            long diff = (oneDayAgo-time)/(1000L * 60 * 60 * 24) + 1;
            if(diff>1) {
                result = diff + " days";
            } else {
                result = diff + " day";
            }
        } else if (time<oneHourAgo) {
            long diff = (oneHourAgo-time)/(1000L * 60 * 60) + 1;
            if(diff>1) {
                result = diff + " hours";
            } else {
                result = diff + " hour";
            }
        } else if (time<oneMinuteAgo) {
            long diff = (oneMinuteAgo-time)/(1000L * 60) + 1;
            if(diff>1) {
                result = diff + " minutes";
            } else {
                result = diff + " minute";
            }
        } else {
            long diff = (now-time)/(1000L) + 1;
            if(diff>1) {
                result = diff + " seconds";
            } else {
                result = diff + " second";
            }
        }
        return result + " ago";
    }

    /**
     * email截取@前面字符串
     */
    public static String getEmailPrefix(String email) {
//        return email.substring(email.indexOf("@")+1); // 获取@后面
        return email.split("@")[0];
    }

    /**
     * 去掉字符串指定字符后的字符串
     */
    public static String removeLastStr(String str, String chr){
        if(StringUtils.isEmpty(str)) {
            return str;
        }
        if(!str.contains(chr)) {
            return str;
        }
        return str.substring(0, str.lastIndexOf(chr));
    }

    /**
     * 去掉字符串最后几个字符
     */
    public static String removeLastChars(String str, int n){
        if(StringUtils.isEmpty(str) || n<=0 || str.length()<=n) {
            return str;
        }

        return str.substring(0, str.length() - n);
    }

    /**
     * 获取ip地址最后一位数字
     * @return
     */
    public static String getIpLastChar(String ip) {
        String lastChar = "";
        if(!StringUtils.isEmpty(ip)) {
            lastChar = String.valueOf(ip.charAt(ip.length()-1));
        }
        return lastChar;
    }

    /**
     * 判断股票代码是否为偶数
     */
    public static boolean checkStockCodeIsEven(String stockCode){
        if(StringUtils.isEmpty(stockCode)) {
            return false;
        }

        try {
            if(checkIsUsStockByCode(stockCode)) {
                return true;
            }

            // 去除后缀
            if(stockCode.contains(".")) {
                stockCode = removeLastChars(stockCode, 3);
            }

            // 最后一位字符
            char lastChar = stockCode.charAt(stockCode.length()-1);
            if(Integer.parseInt(String.valueOf(lastChar)) % 2 == 0) { // 偶数
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return false;
    }

    /**
     * 从基金经理简介里提取学历
     * @param note
     * @return
     */
    public static String getEduFromManagerNote(String note){
        String edu = null;
        if (!StringUtils.isEmpty(note)) {
            if (note.contains("研究生")) {
                edu = "研究生";
            } else if (note.contains("硕士")) {
                edu = "硕士";
            } else if (note.contains("博士")) {
                edu = "博士";
            }
        }
        return edu;
    }

    /**
     * 从工作时长里提取工作年限
     * @param workTime
     * @return
     */
    public static String getWorkYearsFromWorkTime(String workTime) {
        if(!StringUtils.isEmpty(workTime) && workTime.contains("年")) {
            String[] arr = workTime.split("年");
            return arr[0];
        }
        return "1";
    }

    /**
     * 从任期期间里提取开始/截止工作日期
     * @param workPeriod
     * @param separator
     * @param isBegin true-开始日期，false-截止日期
     * @return
     */
    public static String getWorkBeginDateFromWorkPeriod(String workPeriod, String separator, boolean isBegin) {
        if(StringUtils.isEmpty(workPeriod)) {
            return null;
        }

        if (workPeriod.contains(separator)) {
            String[] arr = workPeriod.split(separator);
            if(isBegin) {
                String workBeginDate = arr[0].trim();
                return workBeginDate;
            } else {
                if(workPeriod.contains("至今")) {
                    return JodaUtil.today();
                } else {
                    String workEndDate = arr[1].trim();
                    return workEndDate;
                }
            }
        }

        return null;
    }


    /**
     * 拼接last sql
     */
    public static String getLastSql(String fieldName, List<String> list) {
        StringBuilder lastSql = new StringBuilder();
        lastSql.append(" order by field(").append(fieldName).append(", '");
        for(int i = 0; i<list.size(); i++) {
            if (i == 0) {
                lastSql.append(list.get(i)).append("'");
            } else {
                lastSql.append(",'").append(list.get(i)).append("'");
            }
            if (i == list.size() - 1) {
                lastSql.append(")");
            }
        }
        return lastSql.toString();
    }

    /**
     * 获取分表表名
     */
    public static String getTableName(String tablePrefix, String tsCode) {
        String tableName = "";
        if(tsCode.contains(".")) {
            tableName = tablePrefix + tsCode.substring(tsCode.length()-4, tsCode.length()-3);
        } else {
            tableName = tablePrefix + tsCode.substring(tsCode.length()-1, tsCode.length());
        }
        return tableName;
    }

    /**
     * 根据ts_code判断是否为A股
     */
    public static boolean checkIsAStockByTsCode(String stockTsCode) {
        if(StringUtils.isEmpty(stockTsCode)) {
            return false;
        }
        if(!stockTsCode.contains(".")) {
            return checkIsAStockByCode(stockTsCode);
        }

        if (stockTsCode.contains(".SH") || stockTsCode.contains(".sh")
                || stockTsCode.contains(".SZ") || stockTsCode.contains(".sz")
                || stockTsCode.contains(".BJ") || stockTsCode.contains(".bj")) {
            return true;
        }

        return false;
    }

    /**
     * 根据ts_code判断是否为港股
     */
    public static boolean checkIsHkStockByTsCode(String stockTsCode) {
        if(StringUtils.isEmpty(stockTsCode)) {
            return false;
        }
        if(!stockTsCode.contains(".")) {
            return checkIsHkStockByCode(stockTsCode);
        }

        if(stockTsCode.contains(".HK") || stockTsCode.contains(".hk")) {
            return true;
        }

        return false;
    }

    /**
     * 根据code判断是否为A股
     * 股票代码为6位数字
     */
    public static boolean checkIsAStockByCode(String stockCode) {
        if(StringUtils.isEmpty(stockCode)) {
            return false;
        }

        if(stockCode.contains(".")) {
            return checkIsAStockByTsCode(stockCode);
        }

        if(isNumeric(stockCode) && stockCode.length()==6) {
            return true;
        }

        return false;
    }

    /**
     * 根据code判断是否为港股
     * 股票代码为5位数字
     */
    public static boolean checkIsHkStockByCode(String stockCode) {
        if(StringUtils.isEmpty(stockCode)) {
            return false;
        }

        if(stockCode.contains(".")) {
            return checkIsHkStockByTsCode(stockCode);
        }

        if(isNumeric(stockCode) && stockCode.length()==5) {
            return true;
        }

        return false;
    }

    /**
     * 根据stock_code判断是否为美股
     */
    public static boolean checkIsUsStockByCode(String stockCode) {
        if(StringUtils.isEmpty(stockCode)) {
            return false;
        }

        // 只要stockCode全部是大写英文字母就是美股
        return isAlpha(stockCode);
    }

    /**
     * 判断是否为ETF基金
     */
    public static boolean checkIsETFByName(String name) {
        if(StringUtils.isEmpty(name)) {
            return false;
        }
        return name.contains("ETF") && !name.contains("联接");
    }

    /**
     * 将Map<String, String>拼接成str
     */
    public static String map2Str(Map<String, String> map) {
        if(MapUtils.isEmpty(map)) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        if (map != null && map.size() > 0) {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            sb.deleteCharAt(sb.lastIndexOf("&"));
        }
        return sb.toString();
    }

    /**
     * 将str转换成Map<String, String>
     */
    public static Map<String, String> str2Map(String str) {
        if(StringUtils.isEmpty(str)) {
            return null;
        }

        String[] strs = str.split("&");
        Map<String,String> map = new HashMap<String, String>();
        for (String string : strs) {
            String key = string.split("=")[0];
            String value = string.split("=")[1];
            // 去掉头部空格
            String key1 = key.trim();
            String value1 = value.trim();
            map.put(key1, value1);
        }
        return map;
    }

    /**
     * 将Map<String, String>转换成json字符串
     */
    public static String map2Json(Map<String, String> map) {
        if(MapUtils.isEmpty(map)) {
            return "";
        }

        return JSON.toJSONString(map);
    }

    /**
     * 将json字符串转换成Map<String, String>
     */
    public static Map<String, String> json2Map(String jsonStr) {
        if(StringUtils.isEmpty(jsonStr)) {
            return null;
        }

        return JSON.parseObject(jsonStr, new TypeReference<HashMap<String, String>>() {});
    }

    // 设置默认头像
    public static String getDefaultHeadImgUrl() {
        int randomIndex = new Random().nextInt(DEFAULT_HEAD_IMG_URL_LIST.size());
        return DEFAULT_HEAD_IMG_URL_LIST.get(randomIndex);
    }


    /**
     * 设置排名
     */
    public static String setRank(Integer rank, Integer total) {
        if(rank==null || total==null) {
            return "-";
        }

        return String.valueOf(rank) + "|" + String.valueOf(total);
    }

    /**
     * 获取多个list交集
     */
    public static Collection<String> getIntersection(List<List<String>> lists) {
        // 非空判断
        if(lists == null || lists.size() == 0){
            return null;
        }

        // 判断每一个list是否为空，有一个为空则返回null
        for (List<String> list : lists) {
            if(CollectionUtils.isEmpty(list)) {
                return null;
            }
        }

        // 去除空集合
        List<List<String>> arrayList = new ArrayList<>(lists);
        for (int i = 0; i < arrayList.size(); i++) {
            List<String> list = arrayList.get(i);
            if (list == null || list.size() == 0) {
                arrayList.remove(list);
                i-- ;
            }
        }

        // 都是空集合，返回null
        if(arrayList.size() == 0){
            return null;
        }

        // 第一个集合
        Collection<String> intersection = arrayList.get(0) ;

        // 只有一个非空集合，结果就是它本身
        if(arrayList.size() == 1){
            return intersection;
        }

        // 有多个非空集合，直接挨个求交集
        for (int i = 1; i < arrayList.size(); i++) {
            intersection = CollectionUtils.intersection(intersection, arrayList.get(i));
        }

        return intersection;
    }

    /**
     * 返回空map
     */
    public static HashMap<String, Object> returnEmptyMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("total", 0);
        map.put("list", Collections.emptyList());
        return map;
    }

    /**
     * 获取字符串中相同子串的数量
     * @param str
     * @param subStr
     * @return
     */
    public static int getSubstringCount(String str, String subStr) {
        int count = 0;
        int index = 0;
        while ((index = str.indexOf(subStr, index)) != -1) {
            count++;
            index += subStr.length();
        }
        return count;
    }

    /**
     * 从website中提取url
     * www.chinayinyi.cn/www.sensteed.com  -> www.chinayinyi.cn
     * www.rj-jk.com/  -> www.rj-jk.com/
     * www.crrcgc.cc/sdxc  -> www.crrcgc.cc/sdxc
     * 000752.com/sy  -> http://000752.com/sy
     * www.bainaqiancheng.com;www.bainaqiancheng.com/en  -> www.bainaqiancheng.com
     * @param website
     * @return
     */
    public static String getWebsite(String website) {
        if(StringUtils.isEmpty(website)) {
            return "";
        }

        try {
            if(website.contains("www") && getSubstringCount(website, "www") == 1) {
                return website;
            }

            if(website.contains("http") && getSubstringCount(website, "http") == 1) {
                return website;
            }

            if(website.contains("https") && getSubstringCount(website, "https") == 1) {
                return website;
            }

            if(!(website.startsWith("http") || website.startsWith("www"))){
                return "http://" + website;
            }

            if(website.contains("；") || website.contains(";")) {
                website = website.replaceAll("；", ";");
                if(website.contains(";")) {
                    String[] arr = website.split(";");
                    return arr[0];
                }
            }

            if(website.contains("www") && getSubstringCount(website, "www") > 1) {
                String[] arr = website.split("www");
                return "www" + arr[arr.length-1];
            }

            if(website.contains("http") && getSubstringCount(website, "http") > 1) {
                String[] arr = website.split("http");
                return "http" + arr[arr.length-1];
            }

            if(website.contains("https") && getSubstringCount(website, "https") > 1) {
                String[] arr = website.split("https");
                return "https" + arr[arr.length-1];
            }

            String url = website;
            if(!website.startsWith("http")) {
                url = "http://" + website;
            }
            if(HutoolUtil.isUrl(url)) {
                return website;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), website);
        }

        return "";
    }

    /**
     * 从list里随机取出N个元素
     */
    public static List<String> randomGetFromList(List<String> list, int num) {
        if(CollectionUtils.isEmpty(list)) {
            return null;
        }
        Collections.shuffle(list);
        return list.subList(0, num);
    }

    /**
     * 判断字符串是否在指定范围之内
     */
    public static boolean checkStrInRange(String str, String begin, String end) {
        if(StringUtils.isEmpty(str) || StringUtils.isEmpty(begin) || StringUtils.isEmpty(end)) {
            return false;
        }

        return str.compareTo(begin) >= 0 && str.compareTo(end) <= 0;
    }

    /**
     * 设置分红率
     */
    public static String getCashDivr(String countYear, BigDecimal cashDivr, boolean stockDetail) {
        if(!StringUtils.isEmpty(countYear) && cashDivr!=null) {
            if(stockDetail) {
//                return countYear + "年分红率:" + bigDecimal2String2(increase100Times(cashDivr)) + "%";
                return countYear + "#" + bigDecimal2String2(increase100Times(cashDivr)) + "%";
            } else {
                String result = bigDecimal2String2(increase100Times(cashDivr));
                if(!StringUtils.isEmpty(result)) {
                    return result.replaceAll("-", "0");  // 不存在设置为0
                }
            }
        }
        return "0";
    }

    /**
     * 根据interval计算日期范围
     */
    public static String calcStartEndDateByInterval(short interval, String lastTradeDateBeforeThisYear) {
        DateTime now = JodaUtil.now();
        String startDate = "";
        String endDate = JodaUtil.dateTimeToString(now, JodaUtil.DATE_PATTERN_DEFAULT);
        if(interval == IntervalEnum.LAST_1_WEEK.getType()) { // 近1周
            startDate = JodaUtil.dateTimeToString(JodaUtil.someDaysAgo(now, 7), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_1_MONTH.getType()) { // 近1月
            startDate = JodaUtil.dateTimeToString(JodaUtil.someMonthsAgo(now, 1), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_3_MONTH.getType()) { // 近3月
            startDate = JodaUtil.dateTimeToString(JodaUtil.someMonthsAgo(now, 3), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_6_MONTH.getType()) { // 近6月
            startDate = JodaUtil.dateTimeToString(JodaUtil.someMonthsAgo(now, 6), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_1_YEAR.getType()) { // 近1年
            startDate = JodaUtil.dateTimeToString(JodaUtil.someYearsAgo(now, 1), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_2_YEAR.getType()) { // 近2年
            startDate = JodaUtil.dateTimeToString(JodaUtil.someYearsAgo(now, 2), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_3_YEAR.getType()) { // 近3年
            startDate = JodaUtil.dateTimeToString(JodaUtil.someYearsAgo(now, 3), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_5_YEAR.getType()) { // 近5年
            startDate = JodaUtil.dateTimeToString(JodaUtil.someYearsAgo(now, 5), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.LAST_10_YEAR.getType()) { // 近10年
            startDate = JodaUtil.dateTimeToString(JodaUtil.someYearsAgo(now, 10), JodaUtil.DATE_PATTERN_DEFAULT);
        } else if (interval == IntervalEnum.FROM_THIS_YEAR.getType()) { // 今年以来
            startDate = lastTradeDateBeforeThisYear;
        } else {
            return "";
        }
        return startDate + "#" + endDate;
    }

    /**
     * 判断RSI超买/超卖
     */
    public static Short checkRSI(BigDecimal rsi){
        if(rsi==null){
            return (short)0;
        }

        if(rsi.doubleValue()>=80){
            return (short)1;
        }
        if(rsi.doubleValue()<=20){
            return (short)-1;
        }

        return (short)0;
    }

    /**
     * main
     * @param args
     */
    public static void main(String[] args) {
//    	String[] rightAnswerArr = new String[]{"1", "2", "3"};
//    	String[] userAnswerArr = new String[]{"2", "1", "3"};
//    	System.out.println(checkArrEqual(rightAnswerArr, userAnswerArr));
//    	System.out.println(decrease100Times(new BigDecimal("-5.1")));
//        System.out.println(stripTrailingZeros(new BigDecimal("100.00")));
//        System.out.println(stripTrailingZeros(new BigDecimal("1000.010")));
//    	System.out.println("getUTC0Time:" + getUTC0Time());

//    	System.out.println(bigDeciaml2String(new BigDecimal("1000.010")));
//    	System.out.println(bigDeciaml2String(new BigDecimal("200000.0000000000000123")));
//    	System.out.println(bigDeciaml2String(null));
    	
//    	System.out.println(seconds2HMS(8));
//    	System.out.println(seconds2HMS(38));
//    	System.out.println(seconds2HMS(58));
//    	System.out.println(seconds2HMS(108));
//    	System.out.println(seconds2HMS(180));
//    	System.out.println(seconds2HMS(280));
//        System.out.println(formatSeconds2DHMS(8));
//        System.out.println(formatSeconds2DHMS(280));
//        System.out.println(formatSeconds2DHMS(5080));
//        System.out.println(formatSeconds2DHMS(100082));
//        System.out.println(formatSeconds2DHMS(235083));
//        System.out.println(formatSeconds2DHMS(1235083));
    	
//    	System.out.println(bigDecDiv(new BigDecimal("2010.002000"), new BigDecimal("20053.704593"), 4));
//    	System.out.println(bigDecDiv(new BigDecimal("0.703593"), new BigDecimal("1.002000"), 4));
//    	System.out.println(bigDecDiv(new BigDecimal("406.33000000"), new BigDecimal("16599.00000000"), 4));

//        System.out.println(calcYearProfitRatio(new BigDecimal("0.64"), new BigDecimal("87.16"), 3));
//    	System.out.println(calcYearProfitRatio(new BigDecimal("100"), new BigDecimal("10000"), 1));
//    	System.out.println(calcYearProfitRatio(new BigDecimal("100"), new BigDecimal("10000"), 10));
//    	System.out.println(calcYearProfitRatio(new BigDecimal("100"), new BigDecimal("10000"), 100));
//    	System.out.println(calcYearProfitRatio(new BigDecimal("100"), new BigDecimal("10000"), 1000));
//
//    	System.out.println(calcRealProfitRatio(new BigDecimal("100"), new BigDecimal("10000")));
//    	System.out.println(calcRealProfitRatio(new BigDecimal("100"), new BigDecimal("20000")));
//    	System.out.println(calcRealProfitRatio(new BigDecimal("100"), new BigDecimal("20")));
//    	System.out.println(calcRealProfitRatio(new BigDecimal("100"), new BigDecimal("400.10")));

//        System.out.println(calcYearProfitRatioByProfitRatio(new BigDecimal("-10.16"), 554));
//        System.out.println(calcYearProfitRatioByProfitRatio(new BigDecimal("17.16"), 161));

//        System.out.println(pr2Apr(1.0, 365 * 3));
//        System.out.println(pr2Apr(1.32, 365 * 3 + 355));
    	
//    	System.out.println(calcNumCompare(BigDecimal.valueOf(10.1), BigDecimal.valueOf(10)));
//    	System.out.println(calcNumCompare(BigDecimal.valueOf(100), BigDecimal.valueOf(1.05)));
//    	System.out.println(calcNumCompare(BigDecimal.valueOf(10), BigDecimal.valueOf(0)));
//    	System.out.println(calcNumCompare(BigDecimal.valueOf(0), BigDecimal.valueOf(10)));
//    	System.out.println(calcNumCompare(BigDecimal.valueOf(1), BigDecimal.valueOf(0.5)));

//        System.out.println(calcDoublePercentage(1.0, 3.0, 2));
//        System.out.println(calcPosRatio(BigDecimal.valueOf(1000.0), BigDecimal.valueOf(3000.0), 2));
//        System.out.println(calcIntPercentage(6, 20, 3));
//        System.out.println(percentage(6,20, 3));
//        System.out.println(percentage(3,6, 8));
//        System.out.println(percentage(102,106, 8));
//        System.out.println(percentage(13,18, 5));
//        System.out.println(percentage(3,10, 2));
//
//        System.out.println(percent("3", "10"));
//        System.out.println(percent("3", "6"));
//        System.out.println(percent("5", "6"));
//        System.out.println(percent("481", "3795"));

//      System.out.println(calcChangeRate(BigDecimal.valueOf(10.1), BigDecimal.valueOf(10)));
//    	System.out.println(calcChangeRate(BigDecimal.valueOf(100), BigDecimal.valueOf(1.05)));
//    	System.out.println(calcChangeRate(BigDecimal.valueOf(10), BigDecimal.valueOf(0)));
//    	System.out.println(calcChangeRate(BigDecimal.valueOf(0), BigDecimal.valueOf(10)));
//    	System.out.println(calcChangeRate(BigDecimal.valueOf(1), BigDecimal.valueOf(0.5)));


//        System.out.println(calcChangePercent(BigDecimal.valueOf(1), BigDecimal.valueOf(10), 2));
//        System.out.println(calcChangePercent(BigDecimal.valueOf(5), BigDecimal.valueOf(10), 2));
//        System.out.println(calcChangePercent(BigDecimal.valueOf(9), BigDecimal.valueOf(10), 2));
//        System.out.println(calcChangePercent(BigDecimal.valueOf(10), BigDecimal.valueOf(-2), 2));
//        System.out.println(calcChangePercent(BigDecimal.valueOf(10), BigDecimal.valueOf(0), 2));
//        System.out.println(calcChangePercent(BigDecimal.valueOf(-1), BigDecimal.valueOf(2), 2));

//        System.out.println(calcRiseRate(new BigDecimal("1"), new BigDecimal("1.2")));
//        System.out.println(calcRiseRate(new BigDecimal("1"), new BigDecimal("0.8")));
//        System.out.println(calcRiseRate(new BigDecimal("0.01"), new BigDecimal("0.12")));
//        System.out.println(calcRiseRate(new BigDecimal("36.580000"), new BigDecimal("66.250000")));


//        System.out.println(formatAmount(new Double("0")));
//        System.out.println(formatAmount(new Double("0.0123")));
//        System.out.println(formatAmount(new Double("11.0")));
//        System.out.println(formatAmount(new Double("1234.0")));
//        System.out.println(formatAmount(new Double("12345.01")));
//        System.out.println(formatAmount(new Double("123456.01")));
//        System.out.println(formatAmount(new Double("1234567.0123")));
//        System.out.println(formatAmount(new Double("12345678.01")));
//        System.out.println(formatAmount(new Double("123456789.01")));
//        System.out.println(formatAmount(new Double("402344396956.1496")));
//        System.out.println(formatAmount(new Double("402344396956")));
//        System.out.println(formatAmount(new Double("402344396956.14960000")));

//        System.out.println(formatCount(1L));
//        System.out.println(formatCount(22L));
//        System.out.println(formatCount(333L));
//        System.out.println(formatCount(4444L));
//        System.out.println(formatCount(55555L));
//        System.out.println(formatCount(666666L));
//        System.out.println(formatCount(7777777L));
//        System.out.println(formatCount(88888888L));
//        System.out.println(formatCount(999999999L));

//        System.out.println(formatTimeAgo(1655954588999L));
//        System.out.println(formatTimeAgo(1655953519000L));
//        System.out.println(formatTimeAgo(1655953219000L));
//        System.out.println(formatTimeAgo(1655950819000L));
//        System.out.println(formatTimeAgo(1655949619000L));
//        System.out.println(formatTimeAgo(1655913619000L));
//        System.out.println(formatTimeAgo(1655899219000L));
//        System.out.println(formatTimeAgo(1655863219000L));
//        System.out.println(formatTimeAgo(1655776819000L));
//        System.out.println(formatTimeAgo(1654912819000L));
//        System.out.println(formatTimeAgo(1654048819000L));
//        System.out.println(formatTimeAgo(1651370419000L));
//        System.out.println(formatTimeAgo(1619834419000L));
//        System.out.println(formatTimeAgo(1596247219000L));
//        System.out.println(formatTimeAgo(1590976819000L));

//        System.out.println(getEmailPrefix("guweiqiang2022@test.com"));

//        System.out.println(calcProfit(new BigDecimal("16921.54680000"), new BigDecimal("16695.71195000"), new BigDecimal("0.00160000"), 4));
//        System.out.println(calcProfit(new BigDecimal("0.95828500"), new BigDecimal("0.93828500"), new BigDecimal("17.54000000"), 4));
//        System.out.println(calcProfit(new BigDecimal("6.17698000"), new BigDecimal("5.37698000"), new BigDecimal("3.09000000"), 4));
//        System.out.println(calcProfit(new BigDecimal("1192.32860000"), new BigDecimal("1184.32860000"), new BigDecimal("0.02150000"), 4));
//        System.out.println(calcProfit(new BigDecimal("100.00"), new BigDecimal("200.00"), new BigDecimal("10.00"), 4));
//        System.out.println(calcPr(new BigDecimal("100.00"), new BigDecimal("200.00"), 4));

//        System.out.println(calcExceedApr(new BigDecimal("1.01"), new BigDecimal("2.02"), 35));
//        System.out.println(calcExceedApr(new BigDecimal("2.02"), new BigDecimal("1.00"), 35));
//        System.out.println(calcExceedApr(new BigDecimal("1.03"), new BigDecimal("1.00"), 35));
//        System.out.println(calcExceedApr(new BigDecimal("1.22"), new BigDecimal("10.15"), 35));

//        System.out.println(removeLastStr("600001.SH", "."));
//        System.out.println(removeLastStr("600002.", "."));
//        System.out.println(removeLastStr("600003", "."));

//        System.out.println(removeLastChars("商贸零售(申万)", 4));
//        System.out.println(removeLastChars("电子(申万)", 4));

//        System.out.println(getSuffix("000001.SH"));
//        System.out.println(getSuffix("000001"));
//        System.out.println(getSuffix("000001.SZSE"));

//        System.out.println(checkStockCodeIsEven("000001.SH"));
//        System.out.println(checkStockCodeIsEven("000002"));
//        System.out.println(checkStockCodeIsEven("000009.SZ"));
//
//        System.out.println(removeSuffix("000001.SH"));
//        System.out.println(removeSuffix("000001"));
//        System.out.println(removeSuffix("000001.SZSE"));

//        List<String> sortedStockTsCodeList = new ArrayList<>();
//        sortedStockTsCodeList.add("000001.SZ");
//        sortedStockTsCodeList.add("000002.SZ");
//        sortedStockTsCodeList.add("000003.SZ");
//        sortedStockTsCodeList.add("000004.SZ");
//        System.out.println(getLastSql("ts_code", sortedStockTsCodeList));

//        System.out.println(getTableName("t_stock_daily_basic_", "002001.SZ"));
//        System.out.println(getTableName("t_stock_daily_basic_", "010002"));
//        System.out.println(getTableName("t_stock_daily_basic_", "100303.SZ"));

//        Map<String, String> map = new HashMap<String, String>();
//        map.put("key1", "value1");
//        map.put("key2", "value2");
//        map.put("key3", "value3");
//        System.out.println(map.toString());
//        System.out.println(map2Str(map));
//        System.out.println(str2Map("key1=value1&key2=value2&key3=value3"));
//        System.out.println(map2Json(map));
//        System.out.println(json2Map("{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}"));

//        System.out.println(fromSometime(DateUtil.parse("2023-01-01 08:30:00", DateUtil.DATETIME_PATTERN_DEFAULT)));
//        System.out.println(toToday(DateUtil.parse("2023-08-01 08:30:00", DateUtil.DATETIME_PATTERN_DEFAULT)));
//        System.out.println(toDeadline(DateUtil.parse("2023-08-03 20:00:00", DateUtil.DATETIME_PATTERN_DEFAULT)));
//        System.out.println(toNow(DateUtil.parse("2023-08-02 18:50:00", DateUtil.DATETIME_PATTERN_DEFAULT), new Date()));
//        System.out.println(toNow(DateUtil.parse("2023-08-03 10:00:00", DateUtil.DATETIME_PATTERN_DEFAULT), new Date()));
//        System.out.println(toNow(DateUtil.parse("2023-08-03 18:00:00", DateUtil.DATETIME_PATTERN_DEFAULT), new Date()));
//        System.out.println(toNow(DateUtil.parse("2023-08-03 18:50:00", DateUtil.DATETIME_PATTERN_DEFAULT), new Date()));

//        System.out.println(checkIsHkStockByTsCode("00010"));
//        System.out.println(checkIsHkStockByTsCode("00010.HK"));
//        System.out.println(checkIsHkStockByTsCode("T00018.SH"));
//        System.out.println(checkIsHkStockByCode("00010"));
//        System.out.println(checkIsHkStockByCode("00010.HK"));
//        System.out.println(checkIsHkStockByCode("T00018.SH"));
//        System.out.println(checkIsAStockByTsCode("000102"));
//        System.out.println(checkIsAStockByTsCode("000102.HK"));
//        System.out.println(checkIsAStockByTsCode("00018.SH"));
//        System.out.println(checkIsAStockByCode("000103"));
//        System.out.println(checkIsAStockByCode("000103.SZ"));
//        System.out.println(checkIsAStockByCode("00018"));
        System.out.println(checkIsUsStockByCode("00018"));
        System.out.println(checkIsUsStockByCode("AAPL"));

//        System.out.println(isAlpha(""));
//        System.out.println(isAlpha("1"));
//        System.out.println(isAlpha("A"));
//        System.out.println(isAlpha("v"));
//        System.out.println(isAlpha("A123"));
//        System.out.println(isAlpha("BABA"));

//        System.out.println(isNumeric(""));
//        System.out.println(isNumeric("0"));
//        System.out.println(isNumeric("1.2"));
//        System.out.println(isNumeric("0.3"));
//        System.out.println(isNumeric("10"));
//        System.out.println(isNumeric("-20"));

//        System.out.println(isDouble(""));
//        System.out.println(isDouble("0"));
//        System.out.println(isDouble("-1.8"));
//        System.out.println(isDouble("0.2"));
//        System.out.println(isDouble("10"));
//        System.out.println(isDouble("10.a"));

//        System.out.println(isIntOrDouble(""));
//        System.out.println(isIntOrDouble("0"));
//        System.out.println(isIntOrDouble("-1.8"));
//        System.out.println(isIntOrDouble("0.2"));
//        System.out.println(isIntOrDouble("10"));
//        System.out.println(isIntOrDouble("10.a"));

//        List<String> list1 = Arrays.asList("1", "2", "3", "4", "5");
//        List<String> list2 = Arrays.asList("11", "22", "3", "4", "5");
//        List<String> list3 = Arrays.asList("111", "222", "3", "4", "5");
//        List<String> list4 = Arrays.asList("111", "222", "3", "44", "55");
//        List<List<String>> lists = new ArrayList<>();
//        lists.add(list1);
//        lists.add(list2);
//        lists.add(list3);
//        lists.add(list4);
//        System.out.println(getIntersection(lists));

//        System.out.println(calcChange(new BigDecimal("1.2"), new BigDecimal("0.2")));

//        System.out.println(getWebsite("www.imeik.com"));
//        System.out.println(getWebsite("000752.com/sy"));
//        System.out.println(getWebsite("www.xsmd.com.cn/web/shangShiGongSi"));
//        System.out.println(getWebsite("www.rj-jk.com/"));
//        System.out.println(getWebsite("www.imeik.com/cn/"));
//        System.out.println(getWebsite("www.bainaqiancheng.com;www.bainaqiancheng.com/en"));
//        System.out.println(getWebsite("www.tjpcty.com/www.kingyork.biz"));
//        System.out.println(getWebsite("http://chinayinyi.cn/http://sensteed.com"));
//        System.out.println(getWebsite("https://chinayinyi.cn/https://sensteed.com"));

//        System.out.println(checkStrInRange("20231211", "20231201", "20231220"));
//        System.out.println(checkStrInRange("2023-12-11", "2023-12-01", "2023-12-20"));
//        System.out.println(checkStrInRange("2023-12-11", "2023-11-01", "2023-12-10"));

//        System.out.println(calcStartEndDateByInterval((short) 1));
//        System.out.println(calcStartEndDateByInterval((short) 2));
//        System.out.println(calcStartEndDateByInterval((short) 5));
//        System.out.println(calcStartEndDateByInterval((short) 8));
//        System.out.println(calcStartEndDateByInterval((short) 9));
//        System.out.println(calcStartEndDateByInterval((short) 10));
    }

}
